package org.jsets.fastboot.util;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.function.Function;
import org.apache.commons.codec.binary.Base64;

/**
 * 字符串工具
 * 
 * @author wj596
 *
 */
public abstract class StringUtils {
	/**
	 * UTF-8 编码格式
	 */
	public static final String UTF8 = "UTF-8";
	
	public static final String ISO88591 = "ISO-8859-1";
	

	/**
	 * 空字符
	 */
	public static final String EMPTY = "";

	/**
	 * 占位符
	 */
	public static final String PLACE_HOLDER = "{%s}";

	/**
	 * 分隔符
	 */
	public static final String SEPARATOR = ",";

	private static final char UNDERLINE = '_';

	/**
	 * 获取UUID
	 * 
	 * @return String
	 */
	public static String getUUID() {
		return UUID.randomUUID().toString().replace("-", "");
	}

	/**
	 * 去除两端空格 <br>
	 *
	 * @param string 字符串
	 * @return String
	 */
	public static String trim(final String string) {
		if (Objects.isNull(string)) {
			return "";
		}
		return string.trim();
	}

	/**
	 * 是否为空 <br>
	 * *isEmpty(" ") = false*
	 * 
	 * @param string 字符串
	 * @return boolean
	 */
	public static boolean isEmpty(final String string) {
		return string == null || string.isEmpty();
	}
	
	/**
	 * 是否为空 <br>
	 * *isBlank(" ") = true*
	 * 
	 * @param string 字符串
	 * @return boolean
	 */
	public static boolean isBlank(final String string) {
		int strLen;
		if (string != null && (strLen = string.length()) != 0) {
			for (int i = 0; i < strLen; ++i) {
				if (!Character.isWhitespace(string.charAt(i))) {
					return false;
				}
			}
			return true;
		} else {
			return true;
		}
	}
	
	/**
	 * 断言不为空
	 * 
	 * @param string 字符串
	 * @return boolean
	 */
	public static boolean notEmpty(final String string) {
		return string != null && string.length() > 0;
	}

	/**
	 * 分割字符串，使用‘,’
	 * 
	 * @param str 字符串
	 * @return List<String>
	 */
	public static List<String> split(final String str) {
		if (null == str || "".equals(str)) {
			return Collections.EMPTY_LIST;
		}
		return Arrays.asList(str.split(SEPARATOR));
	}

	/**
	 * 分割字符串，使用指定的分隔符
	 * 
	 * @param str            字符串
	 * @param separatorChars 分隔符
	 * @return List<String>
	 */
	public static List<String> split(final String str, final String separatorChars) {
		if (null == str || "".equals(str)) {
			return Collections.EMPTY_LIST;
		}
		return Arrays.asList(str.split(separatorChars));
	}

	/**
	 * 连接字符串，使用‘,’
	 * 
	 * @param collection 集合
	 * @return String
	 */
	public static String join(final Collection<String> collection) {
		StringBuilder sb = new StringBuilder();
		for (String str : collection) {
			if (sb.length() > 0)
				sb.append(SEPARATOR);
			sb.append(str);
		}
		return sb.toString();
	}

	/**
	 * 连接字符串，使用‘,’
	 * 
	 * @param array 字符串数组
	 * @return String
	 */
	public static String joinComma(final String... array) {
		StringBuilder sb = new StringBuilder();
		for (String str : array) {
			if (sb.length() > 0) {
				sb.append(SEPARATOR);
			}
			sb.append(str);
		}
		return sb.toString();
	}
	
	/**
	 * 连接字符串，使用‘,’
	 * 
	 * @param array 字符串数组
	 * @return String
	 */
	public static String join(final String separatorChars, final String... array) {
		StringBuilder sb = new StringBuilder();
		for (String str : array) {
			if (sb.length() > 0) {
				sb.append(separatorChars);
			}
			sb.append(str);
		}
		return sb.toString();
	}
	
	/**
	 * 连接字符串，使用指定分隔符
	 * 
	 * @param collection     集合
	 * @param separatorChars 分隔符
	 * @return String
	 */
	public static String join(final Collection<String> collection, final String separatorChars) {
		StringBuilder sb = new StringBuilder();
		for (String str : collection) {
			if (sb.length() > 0)
				sb.append(separatorChars);
			sb.append(str);
		}
		return sb.toString();
	}

	/**
	 * 连接字符串，使用‘,’
	 * @param collection<T> 集合
	 * @param convertor 转换为字符串函数
	 * @return
	 */
	public static <T> String join(final Collection<T> collection, Function<T,String> convertor) {
		if(null==collection||collection.size()==0) {
			return "";
		}
		if(null==convertor) {
			return "";
		}

		StringBuilder sb = new StringBuilder();
		for (T item : collection) {
			String str = convertor.apply(item);
			if (sb.length() > 0) {
				sb.append(SEPARATOR);
			}
			sb.append(str);
		}
		return sb.toString();
	}
	
	/**
	 * 转布尔值
	 *
	 * @param str 字符串
	 * @return boolean
	 */
	public static boolean toBoolean(final String str) {
		if (StringUtils.isBlank(str)) {
			return false;
		}

		if ("1".equals(str) || "ok".equals(str) || "true".equals(str)) {
			return true;
		}
		return false;
	}

	/**
	 * 字符串"null"转为""
	 * 
	 * @param string 字符串
	 * @return string
	 */
	public static String nullToBlank(final String string) {
		return string == null ? "" : string;
	}

	/**
	 * 字符串转小写(null安全)
	 * 
	 * @param string 字符串
	 * @return string
	 */
	public static String toLowerCase(final String string) {
		return string == null ? "" : string.toLowerCase();
	}

	/**
	 * 字符串转大写(null安全)
	 * 
	 * @param string 字符串
	 * @return string
	 */
	public static String toUpperCase(final String string) {
		return string == null ? "" : string.toUpperCase();
	}

	/**
	 * 首字母大写
	 * 
	 * @param str 字符串
	 * @return String
	 */
	public static String capitalize(final String str) {
		int strLen;
		if (str == null || (strLen = str.length()) == 0) {
			return str;
		}

		final char firstChar = str.charAt(0);
		final char newChar = Character.toTitleCase(firstChar);
		if (firstChar == newChar) {
			// already capitalized
			return str;
		}

		char[] newChars = new char[strLen];
		newChars[0] = newChar;
		str.getChars(1, strLen, newChars, 1);
		return String.valueOf(newChars);
	}

	/**
	 * 驼峰转下划线
	 */
	public static String camelToUnderline(String param, boolean lowerCase) {
		if (param == null || "".equals(param.trim())) {
			return "";
		}
		int len = param.length();
		StringBuilder sb = new StringBuilder(len);
		for (int i = 0; i < len; i++) {
			char c = param.charAt(i);
			if (Character.isUpperCase(c)) {
				if (i > 0) {
					sb.append(UNDERLINE);
				}
			}
			if (lowerCase) {
				sb.append(Character.toLowerCase(c)); // 统一都转小写
			} else {
				sb.append(Character.toUpperCase(c)); // 统一都转大写
			}
		}
		return sb.toString();
	}

	/**
	 * 符串下划线格式转转驼峰格式
	 * 
	 * @param param 字符串
	 * @return String
	 */
	public static String underlineToCamel(String param) {
		int len = param.length();
		StringBuilder sb = new StringBuilder(len);
		boolean flag = false; // "_" 后转大写标志,默认字符前面没有"_"
		for (int i = 0; i < len; i++) {
			char c = param.charAt(i);
			if (c == '_') {
				flag = true;
				continue; // 标志设置为true,跳过
			} else {
				char tt = Character.toLowerCase(param.charAt(i));
				if (flag && sb.length() > 0) {
					sb.append(Character.toUpperCase(tt));
				} else {
					sb.append(tt);
				}
				flag = false; // 重置标识
			}
		}
		return sb.toString();
	}

	public static String clean(String in) {
		String out = in;

		if (in != null) {
			out = in.trim();
			if (out.equals(EMPTY)) {
				out = null;
			}
		}

		return out;
	}

	public static boolean hasText(String str) {
		if (!hasLength(str)) {
			return false;
		}
		int strLen = str.length();
		for (int i = 0; i < strLen; i++) {
			if (!Character.isWhitespace(str.charAt(i))) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 字符串转Integer，带默认值
	 * 
	 * @param str 字符串
	 * @return Integer
	 */
	public static Integer toInteger(final String str) {
		if(isBlank(str)) {
			throw new IllegalArgumentException("参数不能为空");
		}
		return Integer.valueOf(str);
	}
	
	/**
	 * 字符串转Integer，带默认值
	 * 
	 * @param str 字符串
	 * @param defaultValue 默认值
	 * @return Integer
	 */
	public static Integer toInteger(final String str, int defaultValue) {
		if(isBlank(str)) {
			return defaultValue;
		}
		
		return Integer.valueOf(str);
	}
	

	/**
	 * 字符串转Long，带默认值
	 * 
	 * @param str 字符串
	 * @return Long
	 */
	public static Long toLong(final String str) {
		if(isBlank(str)) {
			throw new IllegalArgumentException("参数不能为空");
		}
		
		return Long.valueOf(str);
	}
	
	/**
	 * 字符串转Long，带默认值
	 * 
	 * @param str 字符串
	 * @param defaultValue 默认值
	 * @return Long
	 */
	public static Long toLong(final String str, long defaultValue) {
		if(isBlank(str)) {
			return defaultValue;
		}
		
		return Long.valueOf(str);
	}
	
	/**
	 * 字符串转Long，带默认值
	 * 
	 * @param str 字符串
	 * @return Long
	 */
	public static Double toDouble(final String str) {
		if(isBlank(str)) {
			throw new IllegalArgumentException("参数不能为空");
		}
		
		return Double.valueOf(str);
	}
	
	/**
	 * 字符串转Long，带默认值
	 * 
	 * @param str 字符串
	 * @param defaultValue 默认值
	 * @return Long
	 */
	public static Double toDouble(final String str, double defaultValue) {
		if(isBlank(str)) {
			return defaultValue;
		}
		
		return Double.valueOf(str);
	}
	
	public static boolean hasLength(String str) {
		return (str != null && str.length() > 0);
	}
	
	/**
	 * 比较内容
	 */
	public static boolean equals(final Object obj1,final Object obj2) {
		if (obj1 == null || obj2 == null) {
			return obj1 == obj2;
		}

		String str1 = null;
		String str2 = null;

		if (obj1 instanceof String) {
			str1 = (String) obj1;
		} else {
			str1 = String.valueOf(obj1);
		}

		if (obj2 instanceof String) {
			str2 = (String) obj2;
		} else {
			str2 = String.valueOf(obj2);
		}

		return str1.equals(str2);
	}
	
	/**
	 * 转换为SQL语句IN条件片段
	 */
	public static String toSQLInStatement(final Collection<?> collection) {
		StringBuilder sb = new StringBuilder();
		for (Object item : collection) {
			if (sb.length() > 0) {
				sb.append(SEPARATOR);
			}
			
			if(item instanceof String) {
				sb.append("'"+item+"'");
			}else {
				sb.append(item.toString());
			}
		}
		return sb.toString();
	}

	/**
	 * 生成'四位一级'编码
	 * <br><br>
	 * 四位一级编码规则，如下：<br>
	 * 四位数字组成一级， 每级最多9999个节点<br><br>
	 * 
	 * 示例，如下：<br>
	 * 安徽公司： 0001<br>
	 * 合肥分公司： 00010001<br>
	 * 芜湖分工：00010002<br>
	 * 合肥分公司高新区分公司： 000100010001<br>
	 * 合肥分公司经开区分公司： 000100010002<br>
	 * <br><br>
	 * 使用这样的编码方法可以方便计算出编码的层级，除4即可<br>
	 * 树形查询时候可以避免递归，使用like即可，如下：<br>
	 * 查询 “合肥分公司”的直接下属单位: like '00010001%' and level = 3<br>
	 * 查询 “合肥分公司”的所有下属单位，使用 like '00010001%'
	 * 
	 * 
	 * @param parent 上级编码
	 * @param levelMax 本级最大编码
	 */
	public static String createFourDigitCode(String parent, String levelMax) {
		String first = "0001";
		if(isBlank(parent)) {
			if(isBlank(levelMax)) {
				return first;
			}else {
				int max = Integer.valueOf(levelMax);
				if(max >=9998) {
					throw new RuntimeException("超出单级的最大编码");
				}
				int curr = max+1;
				return String.format("%04d", curr);
			}
		}
		
		if(isBlank(levelMax)) {
			return parent+first;
		}
		
		if(!levelMax.startsWith(parent)) {
			throw new RuntimeException("parent和levelMax不匹配");
		}
		
		String temp = levelMax.substring(parent.length(), levelMax.length());
		if(temp.length()!=4) {
			throw new RuntimeException("parent和levelMax不匹配");
		}
		
		int max = Integer.valueOf(temp);
		if(max >=9998) {
			throw new RuntimeException("超出单级的最大编码");
		}
		int curr = max+1;
		return parent + String.format("%04d", curr);
	}
	
	public static String URLBase64Encode(String str) {
		try {
			return URLEncoder.encode(new Base64().encodeAsString(str.getBytes()), UTF8);
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage(), e);
		}
	}
	
	public static String URLBase64Decode(String str) {
		try {
			return new String(new Base64().decode(URLDecoder.decode(str, UTF8).getBytes()));
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage(), e);
		}
	}
	
	public static void main(String[] args) {

//		String s = "";
//		String ss  = "";
//		
//		System.out.println(equals(s, ss));
//		
//		System.out.println(createFourDigitCode("",""));
//		System.out.println(createFourDigitCode("","0001"));
//		System.out.println(createFourDigitCode("","0101"));
//		System.out.println(createFourDigitCode("","9997"));
//		System.out.println(createFourDigitCode("0001",""));
//		System.out.println(createFourDigitCode("0001","00010001"));
//		System.out.println(createFourDigitCode("0001","00019997"));
//		System.out.println(createFourDigitCode("88779977","887799770001"));
//		
		//System.out.println(URLBase64Encode("123361437950148609"));
		
		System.out.println(joinComma("-", "a","b"));
		
		
	}
}